﻿using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
using Shipeng.Util;
using SqlSugar;
using System.ComponentModel.DataAnnotations;
using System.Linq.Expressions;
using Yitter.IdGenerator;
using YNTK.Archives.Entitys.Archives;
using YNTK.Archives.Entitys.Dto;
using YNTK.Archives.Interfaces;
using YNTK.Common.Const;
using YNTK.Common.Enum;
using YNTK.Common.Filter;
using YNTK.Data.MongoDB.Repositorie;
using YNTK.Dependency;
using YNTK.DynamicApiController;
using YNTK.FriendlyException;
using YNTK.LinqBuilder;
using YNTK.Mapster;
using YNTK.System.Entitys.Dto.Common;
using YNTK.System.Entitys.Permission;
using YNTK.System.Interfaces.Common;
using YNTK.System.Interfaces.Permission;
using YNTK.System.Interfaces.Resources;

namespace YNTK.Archives
{
    /// <summary>
    /// 档案服务的实现
    /// 版 本：V1.0.0.0
    /// 版 权：云南通科科技有限公司（https://www.yntkkj.com）
    /// 作 者：李仕鹏
    /// 日 期：2022.10.09 
    /// </summary>
    [ApiDescriptionSettings(Tag = "档案管理", Name = "Archives", Order = 791)]
    [Route("api/[controller]")]
    public class ArchivesService : IArchivesService, IDynamicApiController, ITransient
    {
        private readonly ISqlSugarRepository<ArchivesEntity> _archivesRepository;//档案仓储
        private readonly IMongoDBRepository<ArchivesEntity> _archivesMongoDbRepository;//档案mongodb仓储
        private readonly ISqlSugarRepository<ArchivesFileEntity> _archivesFileRepository;//档案相关附件仓储
        private readonly IMongoDBRepository<ArchivesFileEntity> _archivesFileMongoDbRepository;//档案相关附件mongodb仓储
        private readonly ISqlSugarRepository<ArchivesDynamicFieldsEntity> _archivesDynamicFieldsRepository;//档案动态字段仓储
        private readonly IMongoDBRepository<ArchivesDynamicFieldsEntity> _archivesDynamicFieldsMongoDbRepository;//档案动态字段mongodb仓储
       
        private readonly ITkUsersService _tkUsersService;//用户服务
        private readonly IOrganizeService _organizeService;//组织服务
        private readonly IMechanismService _mechanismService;//机构服务
        private readonly IDictionaryService _dictionaryService;//字典服务
        private readonly IFileService _fileService;//文件服务
        private readonly ITkRoleService _tkRoleService;//角色服务
        private readonly HttpContext _httpContext;

        private readonly string _archives = "base_archives";//mongodb中档案数据集名称
        private readonly string _archivesFile = "base_archivesfiles";//mongodb中档案相关附件数据集名称
        private readonly string _archivesDynamicFields = "base_archivesdynamicfields";//mongodb中档案动态字段数据集名称

        /// <summary>
        /// 构造方法依赖注入
        /// </summary>
        /// <param name="archivesRepository">档案仓储</param>
        /// <param name="archivesMongoDbRepository">档案mongodb仓储</param>
        /// <param name="archivesFileRepository">档案相关附件仓储</param>
        /// <param name="archivesFileMongoDbRepository">档案相关附件mongodb仓储</param>
        /// <param name="archivesDynamicFieldsRepository">档案动态字段仓储</param>
        /// <param name="archivesDynamicFieldsMongoDbRepository">档案动态字段mongodb仓储</param>
        /// <param name="tkUsersService">用户服务</param>
        /// <param name="organizeService">组织服务</param>
        /// <param name="mechanismService">机构服务</param>
        /// <param name="dictionaryService">字典服务</param>
        /// <param name="fileService">文件服务</param>
        /// <param name="tkRoleService">角色服务</param>
        public ArchivesService(ISqlSugarRepository<ArchivesEntity> archivesRepository,
            IMongoDBRepository<ArchivesEntity> archivesMongoDbRepository,
            ISqlSugarRepository<ArchivesFileEntity> archivesFileRepository,
            IMongoDBRepository<ArchivesFileEntity> archivesFileMongoDbRepository,
            ISqlSugarRepository<ArchivesDynamicFieldsEntity> archivesDynamicFieldsRepository,
            IMongoDBRepository<ArchivesDynamicFieldsEntity> archivesDynamicFieldsMongoDbRepository,
            ITkUsersService tkUsersService, IOrganizeService organizeService,
            IMechanismService mechanismService, IDictionaryService dictionaryService,
            IFileService fileService, ITkRoleService tkRoleService)
        {
            _archivesRepository = archivesRepository;
            _archivesMongoDbRepository = archivesMongoDbRepository;
            _archivesFileRepository = archivesFileRepository;
            _archivesFileMongoDbRepository = archivesFileMongoDbRepository;
            _archivesDynamicFieldsRepository = archivesDynamicFieldsRepository;
            _archivesDynamicFieldsMongoDbRepository = archivesDynamicFieldsMongoDbRepository;
            _tkUsersService = tkUsersService;
            _organizeService = organizeService;
            _mechanismService = mechanismService;
            _dictionaryService = dictionaryService;
            _fileService = fileService;
            _tkRoleService = tkRoleService;
            _httpContext = App.HttpContext;
        }

        /// <summary>
        /// 获取共享范围类型
        /// </summary>
        /// <returns></returns>
        [HttpGet("sharedscope")]
        public TkResult<List<EnumListDto>> GetSharedScopeList()
        {
            Dictionary<int, string> dic = EnumHelper.EnumToDic<SharedScopeEnum>();
            var result = new List<EnumListDto>();
            foreach (KeyValuePair<int, string> kv in dic)
            {
                result.Add(new EnumListDto { Id = kv.Key.ToStr(), Value = kv.Key, Description = kv.Value });
            }
            return TkResult<List<EnumListDto>>.Success(result);
        }

        /// <summary>
        /// 获取动态字段类型
        /// </summary>
        /// <returns></returns>
        [HttpGet("dynamicfieldtype")]
        public TkResult<List<EnumListDto>> GetDynamicFieldTypeList()
        {
            Dictionary<int, string> dic = EnumHelper.EnumToDic<DynamicFieldTypeEnum>();
            var result = new List<EnumListDto>();
            foreach (KeyValuePair<int, string> kv in dic)
            {
                result.Add(new EnumListDto { Id = kv.Key.ToStr(), Value = kv.Key, Description = kv.Value });
            }
            return TkResult<List<EnumListDto>>.Success(result);
        }

        /// <summary>
        /// 分页获取档案数据
        /// </summary>
        /// <param name="query">查询档案请求模型</param>
        /// <returns></returns>
        [HttpPost("gets")]
        public async Task<TkPageResult<ArchivesListDto>> Gets([FromBody] QueryArchivesFilterRequestModel query)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
                string mechanismId = user.Subject.FindFirst(ClaimConst.MECHANISMID).Value;
                string roleId= user.Subject.FindFirst(ClaimConst.ROLEID).Value;
                //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
                var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

                #region 获取档案数据
                var pageList=new SqlSugarPagedList<ArchivesListDto>();
                #region 组装查询条件
                Expression<Func<ArchivesEntity, bool>> where = m => 
                m.DeleteMark == null && (m.CreatorUserId==userId || 
                (m.SharedScope==0 && m.OrganizeId== organizeId && m.EnabledMark==1) ||
                (m.SharedScope==1 && m.MechanismId == mechanismId && m.EnabledMark == 1) ||
                (m.SharedScope==2 && m.SharedScopeValue.Contains(roleId) && m.EnabledMark == 1) ||
                (m.SharedScope==3 && m.SharedScopeValue.Contains(userId) && m.EnabledMark == 1));

                if (query.enabledMark == 1) where=where.And(m => m.EnabledMark == 1);
                if (query.enabledMark == 0) where=where.And(m => m.EnabledMark != 1);
                if (!string.IsNullOrWhiteSpace(query.organizeId))
                    where = where.And(m => m.OrganizeId == query.organizeId);
                if (!string.IsNullOrWhiteSpace(query.mechanismId))
                {
                    string queryMechanismId = await _mechanismService.GetIdAsync(query.mechanismId, organizeId);
                    where = where.And(m => m.MechanismId == queryMechanismId);
                }
                if (!string.IsNullOrWhiteSpace(query.classifyId))
                {
                    string queryClassifyId = await _dictionaryService.GetIdAsync(query.classifyId, organizeId);
                    where = where.And(m => m.ClassifyId == queryClassifyId);
                }
                if (query.sharedScope != null)
                    where = where.And(m => m.SharedScope == query.sharedScope.GetHashCode());
                if (query.releaseStartTime != null) where = where.And(m => m.ReleaseTime >= query.releaseStartTime);
                if (query.releaseEndTime != null) where = where.And(m => m.ReleaseTime <= query.releaseEndTime);
                if (!string.IsNullOrWhiteSpace(query.keyword))
                    where = where.And(m => m.Title.Contains(query.keyword) || m.Source.Contains(query.keyword) ||
                    m.Publisher.Contains(query.keyword));
                #endregion

                #region 从mongodb中获取档案数据
                //排序生成器
                SortDefinitionBuilder<ArchivesEntity> builderSort = Builders<ArchivesEntity>.Sort;
                //排序约束   Ascending 正序    Descending 倒序
                SortDefinition<ArchivesEntity> sort =builderSort.Ascending(r=>r.SortCode)
                    .Descending(r=>r.CreatorTime);
                //Item1.结果集 Item2.总条数 Item3.总页数
                (List<ArchivesEntity>, int, int) result =
                    await _archivesMongoDbRepository.GetListAsync(_archives,
                    where, query.currentPage, query.pageSize, null, sort);
                pageList.list = result.Item1.Adapt<List<ArchivesListDto>>();
                pageList.pagination = new PagedModel()
                {
                    PageIndex = query.currentPage,
                    PageSize = query.pageSize,
                    Total = result.Item2,
                    PageCount = result.Item3
                };
                #endregion
                if(pageList.list==null || pageList.list.Count()<=0)
                {
                    #region 从sqlserver数据库中获取档案数据
                    var sqlResult = await _archivesRepository.Entities.Where(where)
                         .OrderBy(r => r.SortCode, OrderByType.Asc)
                         .OrderBy(r => r.CreatorTime, OrderByType.Desc)
                         .ToPagedListAsync(query.currentPage, query.pageSize);
                    pageList.list = sqlResult.list.Adapt<List<ArchivesListDto>>();
                    pageList.pagination = sqlResult.pagination;
                    #endregion
                }
                #endregion

                #region 处理返回数据
                if(pageList.list!=null && pageList.list.Count() > 0)
                {
                    var orgIds = pageList.list.Select(r => r.organizeId).Distinct().ToList();
                    var orgs = await _organizeService.GetOrganizeListByIds(orgIds);
                    var mechanismIds = pageList.list.Where(r => !string.IsNullOrWhiteSpace(r.mechanismId))
                        ?.Select(r => r.mechanismId.Split(',').ToList())
                        ?.SelectMany(r => r).Distinct().ToList();
                    var mechanisms = mechanismIds == null || mechanismIds.Count <= 0 
                        ? new List<MechanismEntity>() :
                        await _mechanismService.GetMechanismListAsync(null, mechanismIds);
                    var classifyIds = pageList.list.Select(r => r.classifyId.Split(',').ToList())
                        .SelectMany(r=>r).Distinct().ToList();
                    var classifys = await _dictionaryService.GetDictionaryListByIds(classifyIds);
                    var creatorUserIds= pageList.list.Select(r => r.creatorUserId).Distinct().ToList();
                    var users = await _tkUsersService.GetUserListByIds(creatorUserIds);
                    pageList.list.ForEach(item =>
                    {
                        item.sharedScopeText = EnumHelper.GetEnumDescriptionString
                        (item.sharedScope, typeof(SharedScopeEnum));
                        if (!string.IsNullOrWhiteSpace(item.organizeId))
                            item.organizeName = orgs?.FirstOrDefault(r => r.Id == item.organizeId)?.FullName;
                        if (!string.IsNullOrWhiteSpace(item.mechanismId))
                        {
                            item.mechanismName = string.Join('/', mechanisms
                                ?.Where(r => item.mechanismId.Split(',').ToList().Contains(r.Id))
                                ?.Select(r => r.Name)?.ToList());
                        }
                        if (!string.IsNullOrWhiteSpace(item.classifyId))
                        {
                            item.classifyName = string.Join('/',classifys
                                ?.Where(r => item.classifyId.Split(',').ToList().Contains(r.Id))
                                ?.Select(r=>r.Name)?.ToList());
                        }
                        if (!string.IsNullOrWhiteSpace(item.creatorUserId))
                            item.creatorUserName = users?.FirstOrDefault(r => r.Id == item.creatorUserId)?.RealName;
                    });
                }
                #endregion

                return TkPageResult<ArchivesListDto>.Success(pageList);
            }
            catch (Exception)
            {
                throw YNTKException.Oh("分页获取档案数据发生异常");
            }
        }

        /// <summary>
        /// 获取档案详细信息
        /// </summary>
        /// <param name="id">档案id</param>
        /// <returns></returns>
        [HttpGet("get/{id}")]
        public async Task<TkResult<ArchivesDto>> Get([Required] string id)
        {
            var entity = await _archivesMongoDbRepository.GetAsync(_archives,m=>m.Id==id && m.DeleteMark==null);
            if(entity==null) entity = await _archivesRepository.FirstOrDefaultAsync(r => r.Id == id && r.DeleteMark == null);
            if (entity == null) throw YNTKException.Oh(ErrorCode.Archives0010);
            var result = entity.Adapt<ArchivesDto>();
            result.sharedScopeText = EnumHelper.GetEnumDescriptionString
                        (result.sharedScope, typeof(SharedScopeEnum));
            if (!string.IsNullOrWhiteSpace(result.organizeId) && result.organizeId!= "org00000000")
                result.organizeName = (await _organizeService.GetOrganizeListByIds
                        (new List<string>() { result.organizeId }))?[0].FullName;
            if (!string.IsNullOrWhiteSpace(result.mechanismId) && result.mechanismId != "jg000000")
            {
                result.mechanismName = string.Join('/', (await _mechanismService
                    .GetMechanismListAsync(null, result.mechanismId.Split(',').ToList()))
                    ?.Select(r => r.Name)?.ToList());
            }            
            if (!string.IsNullOrWhiteSpace(result.classifyId))
            {
                result.classifyName = string.Join('/', (await _dictionaryService
                    .GetDictionaryListByIds(result.classifyId.Split(',').ToList()))
                    ?.Select(r => r.Name)?.ToList());
            }
            #region 处理共享范围
            if (!string.IsNullOrWhiteSpace(result.sharedScopeValue))
            {
                //共享范围(0.全组织 1.特定机构 2.特定角色 3.特定用户 4.仅自己可见)
                switch (result.sharedScope)
                {
                    case 0:
                        result.sharedScopeValueText = "全组织";
                        break;
                    case 1:
                        var dic = await _mechanismService.GetIdsAsync(result.sharedScopeValue.Split(',').ToList(), result.organizeId);
                        var values = dic.Values.ToList();
                        result.sharedScopeValueText = string.Join(',', values.Select(r => r.Item2).ToList());
                        result.sharedScopeMechanismValue = values.Select(r => r.Item1.Split(',').ToArray())?.ToList();
                        break;
                    case 2:
                        result.sharedScopeValueText = string.Join(',', (await _tkRoleService
                            .GetTkRoleListByIdsAsync(result.sharedScopeValue.Split(',').ToList()))
                            ?.Select(r => r.Name)?.ToList());
                        break;
                    case 3:
                        result.sharedScopeValueText = string.Join(',', (await _tkUsersService
                           .GetUserListByIds(result.sharedScopeValue.Split(',').ToList()))
                           ?.Select(r => r.RealName)?.ToList());
                        break;
                    case 4:
                        result.sharedScopeValueText = "仅自己可见";
                        break;
                }
            }
            #endregion
            if (!string.IsNullOrWhiteSpace(result.creatorUserId))
                result.creatorUserName = (await _tkUsersService.GetUserInfoByUserId(result.creatorUserId))?.RealName;

            result.fileData =(await GetArchivesFileListAsync(id)).Adapt<List<ArchivesFileListDto>>();
            result.fieldData = (await GetArchivesDynamicFieldsListAsync(id))
                .Adapt<List<ArchivesDynamicFieldsListDto>>();

            #region 累加浏览次数
            entity.ViewCount++;
            await _archivesRepository.Context.Updateable(entity)
                .IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
            await _archivesMongoDbRepository.UpdateAsync(entity, _archives, m => m.Id == entity.Id);
            #endregion

            return TkResult<ArchivesDto>.Success(result);
        }

        /// <summary>
        /// 添加档案
        /// </summary>
        /// <param name="input">添加档案信息请求模型</param>
        /// <returns></returns>
        [HttpPost("add")]
        public async Task Add([FromBody] AddArchivesRequestModel input)
        {
            var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
            string userId = user.Value;
            string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
            string mechanismId = user.Subject.FindFirst(ClaimConst.MECHANISMID).Value;
            string roleId = user.Subject.FindFirst(ClaimConst.ROLEID).Value;
            //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
            var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

            if (await _archivesRepository.AnyAsync(r => r.Title == input.title &&
            r.OrganizeId == organizeId && r.MechanismId== mechanismId && r.DeleteMark == null))
                throw YNTKException.Oh(ErrorCode.Archives0001);

            var entity = input.Adapt<ArchivesEntity>();
            entity.SharedScope = input.sharedScope.GetHashCode();
            entity.OrganizeId = organizeId;
            entity.MechanismId = mechanismId;

            #region 保存档案信息
            var isOk = await _archivesRepository.Context.Insertable(entity)
             .CallEntityMethod(m => m.Creator()).ExecuteReturnEntityAsync();
            _ = isOk ?? throw YNTKException.Oh(ErrorCode.Archives0002);

            entity.Id = isOk.Id;
            var mongoEntity = entity.Adapt<ArchivesEntity>();
            mongoEntity.CreatorUserId = userId;
            mongoEntity.CreatorTime = DateTime.Now;
            var result = await _archivesMongoDbRepository.AddAsync(mongoEntity, _archives);
            if (!result) throw YNTKException.Oh(ErrorCode.Archives0003);
            #endregion
            //保存档案相关附件
            await SaveArchivesFileAsync(entity,input.fileData);
            //保存档案动态字段
            await SaveArchivesDynamicFieldsAsync(entity,input.fieldData);
        }

        /// <summary>
        /// 修改档案信息
        /// </summary>
        /// <param name="input">修改档案信息请求模型</param>
        /// <returns></returns>
        [HttpPut("update")]
        public async Task Update([FromBody] UpdateArchivesRequestModel input)
        {
            var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
            string userId = user.Value;
            string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
            string mechanismId = user.Subject.FindFirst(ClaimConst.MECHANISMID).Value;
            string roleId = user.Subject.FindFirst(ClaimConst.ROLEID).Value;
            //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
            var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

            var entity = await _archivesRepository.FirstOrDefaultAsync(r=>r.Id==input.id && r.DeleteMark==null);
            _ = entity ?? throw YNTKException.Oh(ErrorCode.Archives0010);
            if (entity.CreatorUserId != userId && authenticationType != "2")
                throw YNTKException.Oh(ErrorCode.D1016);
            if (await _archivesRepository.AnyAsync(r => r.Title == input.title && r.Id!=input.id && 
            r.OrganizeId == organizeId && r.MechanismId == mechanismId && r.DeleteMark == null))
                throw YNTKException.Oh(ErrorCode.Archives0001);

            //entity = input.Adapt<ArchivesEntity>();
            entity = input.Mapper(entity);
            entity.SharedScope = input.sharedScope.GetHashCode();
            entity.OrganizeId = organizeId;
            entity.MechanismId = mechanismId;

            #region 保存档案信息
            var isOK = await _archivesRepository.Context.Updateable(entity)
                .IgnoreColumns(ignoreAllNullColumns: true)
                .CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
            if (!(isOK > 0))
                throw YNTKException.Oh(ErrorCode.Archives0011);

            entity.Id = input.id;
            var mongoSaveEntity = entity.Adapt<ArchivesEntity>();
            var mongoEntity = await _archivesMongoDbRepository.GetAsync(_archives, r => r.Id == input.id);
            if (mongoEntity == null)
            {
                mongoSaveEntity.CreatorUserId = userId;
                mongoSaveEntity.CreatorTime = DateTime.Now;
                var result = await _archivesMongoDbRepository.AddAsync(mongoSaveEntity, _archives);
                if (!result) throw YNTKException.Oh(ErrorCode.Archives0003);
            }
            else
            {
                mongoSaveEntity.Id = mongoEntity.Id;
                mongoSaveEntity.CreatorUserId = mongoEntity.CreatorUserId;
                mongoSaveEntity.CreatorTime = mongoEntity.CreatorTime;          
                mongoSaveEntity.LastModifyUserId = userId;
                mongoSaveEntity.LastModifyTime = DateTime.Now;
                var result = await _archivesMongoDbRepository.UpdateAsync(mongoSaveEntity, _archives, m => m.Id == mongoEntity.Id);
                if (!(result.ModifiedCount > 0)) throw YNTKException.Oh(ErrorCode.Archives0003);
            }
            #endregion

            //保存档案相关附件
            await SaveArchivesFileAsync(entity, input.fileData);
            //保存档案动态字段
            await SaveArchivesDynamicFieldsAsync(entity, input.fieldData);
        }

        /// <summary>
        /// 删除档案
        /// </summary>
        /// <param name="id">档案id</param>
        /// <returns></returns>
        [HttpDelete("delete/{id}")]
        public async Task Delete([Required] string id)
        {
            var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
            string userId = user.Value;
            string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
            string mechanismId = user.Subject.FindFirst(ClaimConst.MECHANISMID).Value;
            string roleId = user.Subject.FindFirst(ClaimConst.ROLEID).Value;
            //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
            var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

            var entity = await _archivesRepository.FirstOrDefaultAsync(r => r.Id == id && r.DeleteMark == null);
            _ = entity ?? throw YNTKException.Oh(ErrorCode.Archives0010);
            if (entity.CreatorUserId!=userId && authenticationType!="2")
                throw YNTKException.Oh(ErrorCode.D1016);

            var isOk = await _archivesRepository.Context.Deleteable(entity).ExecuteCommandAsync();
            if (!(isOk > 0))
                throw YNTKException.Oh(ErrorCode.Archives0012);

            var mongoEntity = await _archivesMongoDbRepository.GetAsync(_archives, m => m.Id == id);
            if (mongoEntity != null)
            {
                await _archivesMongoDbRepository.DeleteAsync(_archives,m=>m.Id==id);
            }

            //删除档案相关附件
            await DeleteArchivesFileAsync(id);
        }

        /// <summary>
        /// 更新档案状态(启用/禁用)
        /// </summary>
        /// <param name="id">档案id</param>
        /// <returns></returns>
        [HttpPut("state/{id}")]
        public async Task UpdateState([Required] string id)
        {
            var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
            string userId = user.Value;
            string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
            string mechanismId = user.Subject.FindFirst(ClaimConst.MECHANISMID).Value;
            string roleId = user.Subject.FindFirst(ClaimConst.ROLEID).Value;
            //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
            var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

            var entity = await _archivesRepository.FirstOrDefaultAsync(r => r.Id == id && r.DeleteMark == null);
            _ = entity ?? throw YNTKException.Oh(ErrorCode.Archives0010);
            if (entity.CreatorUserId != userId && authenticationType != "2")
                throw YNTKException.Oh(ErrorCode.D1016);

            var isOk = await _archivesRepository.Context.Updateable<ArchivesEntity>()
                .SetColumns(it => new ArchivesEntity()
            {
                EnabledMark = SqlFunc.IIF(it.EnabledMark == 1, 0, 1),
                LastModifyUserId = userId,
                LastModifyTime = SqlFunc.GetDate()
            }).Where(it => it.Id == id).ExecuteCommandAsync();
            if (!(isOk > 0))
                throw YNTKException.Oh(ErrorCode.Archives0014);

            var mongoSaveEntity = entity.Adapt<ArchivesEntity>();
            mongoSaveEntity.EnabledMark = entity.EnabledMark == 1 ? 0 : 1;
            mongoSaveEntity.LastModifyUserId = userId;
            mongoSaveEntity.LastModifyTime = DateTime.Now;
            var mongoEntity = await _archivesMongoDbRepository.GetAsync(_archives, r => r.Id == id);
            if (mongoEntity == null)
            {                
                var result = await _archivesMongoDbRepository.AddAsync(mongoSaveEntity, _archives);
                if (!result) throw YNTKException.Oh(ErrorCode.Archives0003);
            }
            else
            {
                mongoSaveEntity.Id = mongoEntity.Id;
                mongoSaveEntity.CreatorUserId = mongoEntity.CreatorUserId;
                mongoSaveEntity.CreatorTime = mongoEntity.CreatorTime;
                var result = await _archivesMongoDbRepository.UpdateAsync(mongoSaveEntity, _archives, m => m.Id == mongoEntity.Id);
                if (!(result.ModifiedCount > 0)) throw YNTKException.Oh(ErrorCode.Archives0003);
            }
        }



        #region PublicMethod
        /// <summary>
        /// 获取档案相关附件数据
        /// </summary>
        /// <param name="archivesId">档案id</param>
        /// <returns></returns>
        [NonAction]
        public async Task<List<ArchivesFileEntity>> GetArchivesFileListAsync(string archivesId)
        {
            //从mongodb中获取附件数据
            var result = await _archivesFileMongoDbRepository.GetListAsync(_archivesFile,r=>r.ArchivesId==archivesId);
            if (result == null || result.Count <= 0)
            {
                //从sqlserver数据库中获取附件数据
                result = await _archivesFileRepository.Entities
                    .Where(r=>r.ArchivesId==archivesId).ToListAsync();
            }
            return result;
        }

        /// <summary>
        /// 获取档案动态字段数据
        /// </summary>
        /// <param name="archivesId">档案id</param>
        /// <returns></returns>
        [NonAction]
        public async Task<List<ArchivesDynamicFieldsEntity>> GetArchivesDynamicFieldsListAsync(string archivesId)
        {
            //从mongodb中获取动态字段数据
            var result = await _archivesDynamicFieldsMongoDbRepository.GetListAsync(_archivesDynamicFields, r => r.ArchivesId == archivesId);
            if (result == null || result.Count <= 0)
            {
                //从sqlserver数据库中获取动态字段数据
                result = await _archivesDynamicFieldsRepository.Entities
                    .Where(r => r.ArchivesId == archivesId).ToListAsync();
            }
            return result;
        }

        /// <summary>
        /// 保存档案相关附件
        /// </summary>
        /// <param name="entity">档案信息</param>
        /// <param name="fileData">附件数据</param>
        /// <returns></returns>
        private async Task SaveArchivesFileAsync(ArchivesEntity entity,
            List<ArchivesFileRequestModel> fileData)
        {
            try
            {
                _archivesFileRepository.Ado.BeginTran();
                //删除原数据
                await _archivesFileMongoDbRepository.DeleteAsync(_archivesFile, r => r.ArchivesId == entity.Id);
                await _archivesFileRepository.DeleteAsync(r => r.ArchivesId == entity.Id);
                if (fileData != null && fileData.Count > 0)
                {
                    var files = new List<ArchivesFileEntity>();
                    var file = new ArchivesFileEntity();
                    fileData.ForEach(item =>
                    {
                        file = item.Adapt<ArchivesFileEntity>();
                        file.Id = YitIdHelper.NextId().ToString();
                        file.OrganizeId = entity.OrganizeId;
                        file.MechanismId = entity.MechanismId;
                        file.ArchivesId = entity.Id;
                        file.CreatorUserId = entity.CreatorUserId;
                        file.CreatorTime = entity.CreatorTime;
                        files.Add(file);
                    });
                    //保存到sqlserver                 
                    var isOk=await _archivesFileRepository.Context.Insertable(files).ExecuteCommandAsync();
                    if(!(isOk>0)) throw YNTKException.Oh(ErrorCode.Archives0005);
                    //保存到mongodb
                    var succeed = await _archivesFileMongoDbRepository.AddListAsync(files, _archivesFile);                  
                    if(!succeed) throw YNTKException.Oh(ErrorCode.Archives0004);
                }
                _archivesFileRepository.Ado.CommitTran();
            }
            catch (Exception)
            {
                _archivesFileRepository.Ado.RollbackTran();
                throw YNTKException.Oh(ErrorCode.Archives0006);
            }
        }

        /// <summary>
        /// 保存档案动态字段
        /// </summary>
        /// <param name="entity">档案信息</param>
        /// <param name="fieldData">动态字段数据</param>
        /// <returns></returns>
        private async Task SaveArchivesDynamicFieldsAsync(ArchivesEntity entity,
            List<ArchivesDynamicFieldsRequestModel> fieldData)
        {
            try
            {
                _archivesDynamicFieldsRepository.Ado.BeginTran();
                //删除原数据
                await _archivesDynamicFieldsMongoDbRepository.DeleteAsync(_archivesDynamicFields, r => r.ArchivesId == entity.Id);
                await _archivesDynamicFieldsRepository.DeleteAsync(r => r.ArchivesId == entity.Id);
                if (fieldData != null && fieldData.Count > 0)
                {
                    var fields = new List<ArchivesDynamicFieldsEntity>();
                    var field = new ArchivesDynamicFieldsEntity();
                    fieldData.ForEach(item =>
                    {
                        field = item.Adapt<ArchivesDynamicFieldsEntity>();
                        field.Id = YitIdHelper.NextId().ToString();
                        field.OrganizeId = entity.OrganizeId;
                        field.MechanismId = entity.MechanismId;
                        field.ArchivesId = entity.Id;
                        field.CreatorUserId = entity.CreatorUserId;
                        field.CreatorTime = entity.CreatorTime;
                        fields.Add(field);
                    });
                    //保存到sqlserver                 
                    var isOk = await _archivesDynamicFieldsRepository.Context.Insertable(fields).ExecuteCommandAsync();
                    if (!(isOk > 0)) throw YNTKException.Oh(ErrorCode.Archives0009);
                    //保存到mongodb
                    var succeed = await _archivesDynamicFieldsMongoDbRepository.AddListAsync(fields, _archivesDynamicFields);
                    if (!succeed) throw YNTKException.Oh(ErrorCode.Archives0008);
                }
                _archivesFileRepository.Ado.CommitTran();
            }
            catch (Exception)
            {
                _archivesDynamicFieldsRepository.Ado.RollbackTran();
                throw YNTKException.Oh(ErrorCode.Archives0007);
            }
        }
      
        /// <summary>
        /// 删除档案相关附件数据
        /// </summary>
        /// <param name="archivesId">档案id</param>
        /// <returns></returns>
        private async Task DeleteArchivesFileAsync(string archivesId)
        {
            try
            {
                var files = await GetArchivesFileListAsync(archivesId);
                if (files != null && files.Count > 0)
                {
                    //删除mongodb数据
                    await _archivesFileMongoDbRepository.DeleteAsync(_archivesFile, r => r.ArchivesId == archivesId);
                    //删除sqlserver数据
                    await _archivesFileRepository.DeleteAsync(r => r.ArchivesId == archivesId);
                    //删除文件
                    var deleteFiles = files.Adapt<List<FileListDto>>();
                    _fileService.DeleteFiles(deleteFiles);
                }
            }
            catch (Exception)
            {
                throw YNTKException.Oh(ErrorCode.Archives0013);
            }
        }
        #endregion




    }
}
